# -*- coding: utf-8 -*-
import logging
import os
import configparser
import sys

cnf_file = "myback.ini"
config = configparser.ConfigParser()
config.read(cnf_file)

logging.basicConfig(level=logging.INFO)


stop_at = sys.argv[1]
inner_backup_dir = config.get("myback", "inner_backup_dir")
inner_work_dir = config.get("myback", "inner_work_dir")
xtrabackuplog_name = "backuplog.log"
backupfilelist = os.path.join(inner_backup_dir, "backupfilelist.log")
lastFile = os.path.join(inner_work_dir, "lastFile.log")


# 返回备份日志中的最新的一个早于stop_at时间的完整备份，以及其后面的增量备份
def get_restorefile_list():
    list_backup = []
    list_restore_file = []
    if os.path.exists(backupfilelist):
        with open(backupfilelist, 'r') as f:
            lines = f.readlines()
            for line in lines:
                list_backup.append(line.replace("\n", ""))
    if (list_backup):
        for i in range(len(list_backup) - 1, -1, -1):
            list_restore_file.append(list_backup[i])
            backup_name = list_backup[i].split("|")[2]
            if "full" in backup_name:
                full_backup_time = list_backup[i].split("|")[1]
                if (stop_at < full_backup_time):
                    break
                else:
                    list_restore_file = None
    # restore file in the list_restore_log
    list_restore_file.reverse()
    return list_restore_file


# 解压缩需要还原的备份文件，包括一个完整备份以及N个增量备份（N>=0）
def uncompress_backup_file():
    list_restore_backup = get_restorefile_list()
    print("The following backup files will be restored according to {0}:".format(stop_at))
    print(list_restore_backup)

    # 如果没有生成时间早于stop_at的完整备份，无法恢复，退出
    if not list_restore_backup:
        print("There is no backup file available for recovery before ${0}".format(stop_at))
        exit(1)

    for restore_log in list_restore_backup:
        # 解压备份文件
        backup_name = restore_log.split("|")[2]
        backup_path = restore_log.split("|")[2]
        backup_full_name = os.path.join(inner_backup_dir, backup_path, backup_name)
        backup_path = os.path.join(inner_backup_dir, restore_log.split("|")[-1])
        os.system('''[ ! -d {0} ] && mkdir -p {0}'''.format(os.path.join(inner_work_dir, backup_name)))
        os.system(
            "xbstream -x < {0}.xbstream -C {1}".format(backup_full_name, os.path.join(inner_work_dir, backup_name)))
        os.system("cd {0}".format(os.path.join(inner_work_dir, backup_name)))
        os.system('''for f in `find {0}/ -iname "*\.qp"`; do qpress -dT4 $f  $(dirname $f) && rm -f $f; done'''.format(
            os.path.join(inner_work_dir, backup_name)))

        current_backup_begin_time = None
        current_backup_end_time = None
        # 比较当前备份的结束时间和stop_at,如果当前备份开始时间小于stop_at并且结束时间大于stop_at，解压缩备份结束
        with open(os.path.join(inner_work_dir, backup_name, "xtrabackup_info"), 'r') as f:
            for line in f:
                if line and line.split("=")[0].strip() == "start_time":
                    current_backup_begin_time = line.split("=")[1].strip()
                if line and line.split("=")[0].strip() == "end_time":
                    current_backup_end_time = line.split("=")[1].strip()
        # 按照stop_at时间点还原的最后一个数据库备份,结束从第一个完整备份开始的解压过程
        if current_backup_begin_time <= stop_at <= current_backup_end_time:
            break

    with open(lastFile, 'w+') as f:
        f.write(backup_name + '\n')
    # 返回最后一个备份文件，需要备份文件中的xtrabackup_info，解析出当前备份的end_time，从而确认需要哪些binlog
    return backup_name


if __name__ == '__main__':
    try:
        uncompress_backup_file()
    except Exception as e:
        print(e)
